<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;
use App\Exceptions\BadException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
use App\Helpers\ApiResponseTrait;
use Illuminate\Support\Facades\Log;

class Handler extends ExceptionHandler
{
    use ApiResponseTrait;
    /**
     * A list of the exception types that are not reported.
     *
     * @var array<int, class-string<Throwable>>
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array<int, string>
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     *
     * @return void
     */
    public function register()
    {
        $this->reportable(function (Throwable $e) {
            //
        });
    }

    /**
     * 异常处理
     * @param $request
     * @param Throwable $exception
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     * @throws Throwable
     */
    public function render($request, Throwable $exception)
    {
        // 如果是在开发模式下（APP_DEBUG = true），则返回 Laravel 默认的详细错误页面
        if (config('app.debug')) {
            return parent::render($request, $exception);
        }

        // 检查是否为自定义的 BadException
        if ($exception instanceof BadException) {
            return $this->error($exception->getMessage(), $exception->getStatusCode());
        }

        // 如果验证数据失败则返回错误信息
        if ($exception instanceof ValidationException) {
            // 获取验证错误并格式化为 JSON
            $errors = $exception->validator->errors();
            $errors = $errors->first(); // 提取每个字段的第一个错误信息
            return $this->unprocessableEntity($errors ?: '验证失败');
        }
        
        // 如果路由不存在
        if ($exception instanceof NotFoundHttpException) {
            return $this->error('路由不存在', 404);
        }

        // 如果是 HttpException，则返回 HTTP 状态码和消息
        if ($this->isHttpException($exception)) {
            return $this->error($exception->getMessage() ?: '请求异常', $exception->getStatusCode());
        }

        // 如果是认证异常，则返回未授权状态
        if ($exception instanceof \Illuminate\Auth\AuthenticationException) {
            return $this->unauthorized('UnAuthorized');
        }

        // 其他异常统一记录到日志
        Log::error($exception);

        // 生产环境下返回一个通用的错误响应
        return $this->error('Internal Server Error', 500);
    }
}
